# -*- coding: utf-8 -*-
from django.http import JsonResponse
from ApiManager.models import UserInfo, ProjectInfo, DebugTalk, ModuleInfo, TestCaseInfo, EnvInfo
import logging
from django.db import DataError
import json
from django.conf import settings
from django.core.serializers import serialize
import os
import yaml
import shutil
from ApiAutoTest.tasks import runCaseWorker, moduleAddWorker, caseConfigAdd
from django.core.paginator import Paginator
import time

# from haystack.views import SearchView

logger = logging.getLogger('ApiAutoTest')
base_dir = settings.BASE_DIR
project_dir = os.path.join(base_dir, "project")


# class MySearchView(SearchView):
#     def create_response(self):
#         keyword = self.request.GET.get('q', None)  # 关键子为q\
#         print(keyword)
#         data = dict()
#         context = self.get_context()
#         if not keyword:
#             return JsonResponse({'message': '没有相关信息'})
#         else:
#             print(context)
#             for item in context.get("page").object_list:
#                 data["project_name"] = item.object.project_name
#                 data["responsible_name"] = item.object.responsible_name
#                 data['test_user'] = item.object.test_user
#                 return JsonResponse(data)


# 登录装饰器
def login_check(func):
    data = dict()

    def wrapper(request, *args, **kwargs):
        if not request.session.get('login_status'):
            data["loginMsg"] = "0"
            data["msg"] = "用户未登录"
            return JsonResponse(data=data)
        return func(request, *args, **kwargs)

    return wrapper


# api/register
def register(request):
    """
    注册用户
    :return:
    """
    data = dict()
    if request.method == "POST":
        try:
            login_info = json.loads(request.body.decode('utf-8'))
            username = login_info.get("registerInfo").pop("username")
            password = login_info.get("registerInfo").pop('password')
            email = login_info.get("registerInfo").pop('email')
            user_info = UserInfo.objects
            if user_info.filter(username=username).filter(status=1).count() > 0:
                logger.debug(f'{username} 已被其他用户注册')
                data["msg"] = '该用户名已被注册，请更换用户名'
                data["registerMsg"] = "0"
            user_info.create(username=username, password=password, email=email)
            logger.info(f'新增用户：{username}')
            data["msg"] = f'新增用户：{username}成功'
            data["registerMsg"] = "1"
        except DataError:
            logger.error('信息输入有误')
            data["msg"] = f'注册用户失败'
            data["registerMsg"] = "0"
    return JsonResponse(data=data)


# api/login
def login(request):
    """
    登录用户
    :param request:
    :return:
    """
    data = dict()
    if request.method == "POST":
        login_info = json.loads(request.body.decode('utf-8'))
        print(login_info, "9999999999999999999999999")
        username = login_info.get("username")
        password = login_info.get('password')
        if UserInfo.objects.filter(username__exact=username).filter(password__exact=password).count() == 1:
            logger.info(f'{username} 登录成功')
            request.session["login_status"] = True
            request.session["username"] = username
            data["msg"] = "登录成功"
            data["username"] = username
            data["msgCode"] = "1"
        else:
            logger.info(f'{username} 登录失败, 请检查用户名或者密码')
            request.session["login_status"] = False
            data["msg"] = "登录失败"
            data["msgCode"] = "0"
    elif request.method == 'GET':
        username = request.GET.get('username')
        password = request.GET.get('password')
        data["msg"] = "请求错误"
        logger.info(f'{username} 登录失败, 请检查用户名或者密码')
    return JsonResponse(data=data)


# api/projectAdd
def projectAdd(request):
    """
    添加项目
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "POST":
        project_info = json.loads(request.body.decode("utf-8")).get("projectInfo")
        project_obj = ProjectInfo.objects
        project_name = project_info.get("project_name")
        if project_obj.get_pro_name(project_name) < 1:
            try:
                obj = project_obj.create(**project_info)
                project_id = obj.id
                # 生成项目文件目录
                project_case_dir = os.path.join(project_dir, f'ApiProject{project_id}')
                if not os.path.exists(project_case_dir):
                    os.makedirs(project_case_dir)
                # 写入到数据库
                belong_project = project_obj.get(project_name=project_name)
                data["msg"] = "新增项目成功"
                data["msgCode"] = "1"
                logger.info(f'项目添加成功：{project_info}')

            except DataError:
                data["msg"] = '项目信息过长'
                data["msgCode"] = "0"
            except Exception as e:
                logging.error(f'项目添加异常：{e}')
                data["msg"] = '添加失败，请重试'
                data["msgCode"] = "0"
        else:
            logger.info('项目名称重复')
            data['msgCode'] = '0'
            data['msg'] = '项目名称重复'
        return JsonResponse(data=data)


# api/projectList
def projectList(request):
    """
    获取项目（不要与searchProject合并）
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        data_rq = request.GET
        logger.info(f"获取项目时传递的参数：{data_rq}")
        type_rq = request.GET.get('type')  # 请求类型,判断是否为新增模块页面还是项目列表页发起的请求
        if type_rq == 'moduleAdd':  # 添加模块
            logger.info("新增模块时获取项目")
            project_id = request.GET.get('projectId')
            if project_id and project_id != 'undefined':
                project_list = ProjectInfo.objects.filter(id=project_id)
            else:
                project_list = ProjectInfo.objects.all()
            # data["projectList"] = json.loads(serialize("json", project_list))
        elif type_rq == 'caseAdd':  # 添加用例
            logger.info('新增用例时获取项目')
            module_id = request.GET.get('moduleId')
            if module_id and module_id != 'undefined':
                project_list = ProjectInfo.objects.filter(moduleinfo__id=module_id)
            else:
                project_list = ProjectInfo.objects.all()
        else:
            logger.info("项目列表页面获取项目")
            project_list = ProjectInfo.objects.all()
            data["projectNum"] = project_list.count()
            # 分页
            pg = Paginator(project_list, 10)
            project_list = pg.page(1).object_list
        data["msg"] = "success"
        data["msgCode"] = "1"
        data["projectList"] = json.loads(serialize("json", project_list))
    return JsonResponse(data=data)


def projectEdit(request):
    """
    编辑项目
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "PUT":
        project_info = json.loads(request.body.decode("utf-8")).get('projectInfo')
        logger.info(f'项目修改后内容为：{project_info}')
        project_id = project_info.get('id')
        project_name = project_info.get('fields').get('project_name')
        if not ProjectInfo.objects.filter(project_name=project_name):
            obj = ProjectInfo.objects.get(id=project_id)
            obj.project_name = project_name
            obj.responsible_name = project_info.get('fields').get('responsible_name')
            obj.test_user = project_info.get('fields').get('test_user')
            obj.dev_user = project_info.get('fields').get('dev_user')
            obj.publish_app = project_info.get('fields').get('publish_app')
            obj.simple_desc = project_info.get('fields').get('simple_desc')
            obj.other_desc = project_info.get('fields').get('other_desc')
            obj.save()
            data["msgCode"] = "1"
            data["msg"] = "修改项目成功"
        else:
            data["msgCode"] = "0"
            data['msg'] = '项目名称重复'
            logger.info("项目名称重复")
    return JsonResponse(data=data)


# api/projectDel
def projectDel(request):
    """
    删除项目
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "DELETE":
        project_id = json.loads(request.body.decode("utf-8")).get("projectId")
        logger.info(f"获取待删除的项目Id为：{project_id}")
        obj = ProjectInfo.objects.get(id=project_id)
        obj.delete()
        # 删除项目目录
        project_case_dir = os.path.join(base_dir, f'project/ApiProject{project_id}')
        shutil.rmtree(project_case_dir)
        data["msgCode"] = "1"
        data["msg"] = f"删除项目成功:{obj}"
    return JsonResponse(data=data)


# api/searchProject
def searchProject(request):
    """
    查询项目
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        search_info = json.loads(request.GET.get("searchInfo"))
        logger.info(f"查询项目内容为：{search_info}")
        project_name = search_info.get('projectName')
        if project_name:
            project_list = ProjectInfo.objects.filter(project_name__icontains=project_name)
        else:
            project_list = ProjectInfo.objects.all()
        data["projectNum"] = project_list.count()
        # 分页
        page_size = search_info.get('pageSize')  # 每页显示的数量
        pg = Paginator(project_list, page_size)
        if data["projectNum"] <= page_size:  # 当前端页码处于非第一页但查询结果又小于当前每页显示数量时，将页码重置为第一页.需要将页码传递给前端
            current_page = 1
        else:
            current_page = search_info.get('currentPage')  # 当前页码
        project_list = pg.page(current_page).object_list
        data['currentPage'] = current_page
        data['pageSize'] = page_size
        data["msg"] = "查询项目成功"
        data["msgCode"] = '1'
        data["username"] = username
        data["projectList"] = json.loads(serialize("json", project_list))
    return JsonResponse(data=data)


# api/getModuleNum/
def getModuleNum(request):
    """
        根据项目id获取模块数量
        :param request:
        :return:
        """
    data = dict()
    if request.method == "GET":
        project_id = request.GET.get('projectId')
        case_list = ModuleInfo.objects.filter(belong_project_id=project_id)
        data['moduleNum'] = case_list.count()
    return JsonResponse(data=data)


# api/moduleList
def moduleList(request):
    """
    模块列表
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        project_id = request.GET.get("projectId")
        module_id = request.GET.get("moduleId")
        type_rq = request.GET.get('type')
        if type_rq == 'caseAdd':
            logger.info("新增用例时获取模块")
            if module_id:
                logger.info(f"根据（moduleId={module_id}）获取模块列表")
                module_list = ModuleInfo.objects.filter(id=module_id)
            elif project_id:
                logger.info(f"根据项目（projectId={project_id}）获取模块列表")
                module_list = ModuleInfo.objects.filter(belong_project_id=project_id)
            else:
                module_list = ModuleInfo.objects.all()
        else:
            logger.info("模块列表页面初始时获取模块,需要分页")
            if project_id:  # 通过项目列表跳转模块列表页面时获取模块
                logger.info(f"根据项目（projectId={project_id}）获取模块列表")
                module_list = ModuleInfo.objects.filter(belong_project_id=project_id)
            else:  # 直接进入模块列表页面获取模块
                module_list = ModuleInfo.objects.all()
            data['moduleNum'] = module_list.count()
            # 分页
            pg = Paginator(module_list, 10)
            module_list = pg.page(1).object_list
        data['msgCode'] = '1'
        data['msg'] = '获取module数据成功'
        data['moduleList'] = json.loads(serialize("json", module_list))
    return JsonResponse(data=data)


# api/moduleAdd
def moduleAdd(request):
    """
    添加模块
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "POST":
        logger.info(request.body)
        module_info = json.loads(request.body.decode("utf-8")).get("moduleInfo")
        logger.info(module_info)
        module_list = ModuleInfo.objects
        module_obj = module_list.insert_module(**module_info)
        module_id = module_obj.id
        project_id = module_obj.belong_project_id
        # celery异步创建项目模块文件
        logger.info(f"异步生成模块文档")
        moduleAddWorker.delay(project_id, module_id)
        # 生成对应的debugtalk表内容
        DebugTalk.objects.create(belong_project_id=project_id, belong_module_id=module_id, debugtalk='#debugtalk.py')
        # 生成对应的envinfo表内容
        EnvInfo.objects.create(belong_project_id=project_id, belong_module_id=module_id, content='')
        data["msgCode"] = "1"
        data["msg"] = "新增模块成功"
    return JsonResponse(data)


# api/moduleEdit
def moduleEdit(request):
    """
    模块编辑
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "PUT":
        module_info = json.loads(request.body.decode("utf-8")).get("moduleFields")
        logger.info(module_info)
        # 获取初始项目id
        project_origin_id = json.loads(request.body.decode("utf-8")).get("projectOriginId")
        # 编辑内容存储到数据库
        obj = ModuleInfo.objects.get(id=module_info.get('id'))
        obj.module_name = module_info.get('fields').get('module_name')
        obj.belong_project_id = module_info.get('fields').get('belong_project')
        obj.test_user = module_info.get('fields').get('test_user')
        obj.simple_desc = module_info.get('fields').get('simple_desc')
        obj.other_desc = module_info.get('fields').get('other_desc')
        obj.save()
        # 判断模块所属项目是否变化，当有变化时，将模块目录移动到相应目录下
        if project_origin_id == obj.belong_project_id:
            pass
        else:
            module_old_path = os.path.join(project_dir, f'ApiProject{project_origin_id}/ApiModule{obj.id}')
            module_new_path = os.path.join(project_dir, f'ApiProject{obj.belong_project_id}/ApiModule{obj.id}')
            shutil.move(module_old_path, module_new_path)
            logger.info(f"成功移动模块ApiModule{obj.id}到新项目ApiProject{obj.belong_project_id}目录下")
        data["msgCode"] = "1"
        data["msg"] = "编辑模块成功"
    return JsonResponse(data)


# api/moduleDel/
def moduleDel(request):
    """
    删除模块
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "DELETE":
        module_info = json.loads(request.body.decode("utf-8")).get("moduleInfo")
        module_id = module_info.get("pk")
        module_obj = ModuleInfo.objects.get(id=module_id)
        module_obj.delete()
        logger.info(f"成功删除的模块Id为：{module_id}")
        # 删除debugtalk表中的对应的数据
        debugtalk_obj = DebugTalk.objects.filter(belong_module_id=module_id)
        debugtalk_obj.delete()
        # 删除项目目录下的模块目录
        project_id = module_info.get('fields').get('belong_project')
        module_path = os.path.join(project_dir, f'ApiProject{project_id}/ApiModule{module_id}')
        if os.path.exists(module_path):
            shutil.rmtree(module_path)
        logger.info(f"成功删除项目目录下的模块：ApiModule{module_id}")
        data["msgCode"] = "1"
        data["msg"] = f"删除模块成功"
    return JsonResponse(data=data)


# /api/getCaseNum/
def getCaseNum(request):
    """
    根据模块id获取用例数量
    :param request:
    :return:
    """
    data = dict()
    if request.method == "GET":
        module_id = request.GET.get('moduleId')
        case_list = TestCaseInfo.objects.filter(belong_module_id=module_id)
        data['caseNum'] = case_list.count()
    return JsonResponse(data=data)


# api/searchModule/
def searchModule(request):
    """
    模块搜索
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        searchInfo = json.loads(request.GET.get('searchInfo'))
        logger.info(f'查询的模块信息：{searchInfo}')
        project_id = searchInfo.get('projectId')
        module_name = searchInfo.get('moduleName')
        if project_id:
            module_list = ModuleInfo.objects.filter(belong_project_id=project_id).filter(module_name__icontains=module_name)
        else:
            module_list = ModuleInfo.objects.all()
        data['moduleNum'] = module_list.count()
        page_size = searchInfo.get('pageSize')
        pg = Paginator(module_list, page_size)
        if data['moduleNum'] <= page_size:  # 当前端页码处于非第一页但查询结果又小于当前每页显示数量时，将页码重置为第一页.需要将页码传递给前端
            current_page = 1
        else:
            current_page = searchInfo.get('currentPage')  # 当前页码
        module_list = pg.page(current_page)
        data['currentPage'] = current_page
        data["msg"] = "查询项目成功"
        data["msgCode"] = '1'
        data["username"] = username
        data["moduleList"] = json.loads(serialize("json", module_list))
    return JsonResponse(data=data)


# api/caseList/
def caseList(request):
    """
    获取测试用例列表
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        module_id = request.GET.get('moduleId')
        if module_id:
            logger.info(f"根据模块（moduleId={module_id}）获取用例列表")
            case_list = TestCaseInfo.objects.filter(belong_module_id=module_id)
        else:
            case_list = TestCaseInfo.objects.all()
        data['caseNum'] = case_list.count()
        # 分页
        pg = Paginator(case_list, 10)  # 每页展示10条数据
        case_list = pg.page(1).object_list  # 展示第一页
        data["caseList"] = json.loads(serialize("json", case_list))
        data["msg"] = "success"
        data["msgCode"] = "1"
    return JsonResponse(data=data)


# api/caseAdd/
def caseAdd(request):
    """
    添加用例
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "POST":
        data_req = json.loads(request.body.decode("utf-8"))
        case_info = data_req.get("caseInfo")
        logger.info(f'添加用例：{case_info}')
        case_debugTalkInfo = data_req.get('debugTalkInfo')
        case_envInfo = data_req.get('envInfo')
        case_type = data_req.get('type')
        if case_type == 'single':
            case_name = case_info.get("name")
            belong_project = case_info.get('belong_project')
            belong_module_id = case_info.get('belong_module')
            author = case_info.get('author')
            request = {
                'base_url': case_info.get('request').get('base_url'),
                'url': case_info.get('request').get('url'),
                'method': case_info.get('request').get('method'),
                'headers': case_info.get('request').get('headers'),
                'json': case_info.get('request').get('json'),
                'variables': case_info.get('request').get('variables'),
                'validate': case_info.get('request').get('validate'),
            }
            case_obj = TestCaseInfo.objects.create(name=case_name, type_case=case_type, belong_project_id=belong_project, belong_module_id=belong_module_id, author=author, request=request)
            # 生成用例文件
            case_id = case_obj.id
            # 用例名称
            case_name = case_obj.name
            # 请求base_url
            base_url = 'http://' + request.get('base_url')
            # 请求头
            case_headers = {}
            for i in request.get("headers"):
                key = i.get('Key')
                value = i.get('Value')
                case_headers[key] = value
            # 请求数据
            case_json = {}
            for i in request.get("json"):
                key = i.get('Key')
                Type = i.get('Type')
                value = i.get('Value')
                if Type == "int":
                    case_json[key] = int(value)
                elif Type == "float":
                    case_json[key] = float(value)
                elif Type == "string":
                    case_json[key] = str(value)
                else:
                    case_json[key] = value
            # 请求方法
            case_method = request.get("method")
            # 请求地址
            case_url = request.get("url")
            # 变量
            case_variables = {}
            for i in request.get("variables"):
                key = i.get('Key')
                Type = i.get('Type')
                value = i.get('Value')
                if Type == "int":
                    case_variables[key] = int(value)
                elif Type == "float":
                    case_variables[key] = float(value)
                elif Type == "string":
                    case_variables[key] = str(value)
                else:
                    case_variables[key] = value
            # 断言
            case_validate = []
            for i in request.get("validate"):
                Check = i["Check"]
                Comparator = i["Comparator"]
                Type = i.get("Type")
                Expect = i['Expect']
                dic = dict()
                dic["check"] = Check
                dic["comparator"] = Comparator
                if Type == "int":
                    dic['expect'] = int(Expect)
                elif Type == "float":
                    dic['expect'] = float(Expect)
                elif Type == "string":
                    dic['expect'] = str(Expect)
                else:
                    dic['expect'] = Expect
                case_validate.append(dic)
            # yaml文件内容
            case_yml = {
                "name": case_name,
                "variables": case_variables,
                'base_url': base_url,
                "request": {
                    "url": case_url,
                    "method": case_method,
                    "headers": case_headers,
                    "json": case_json
                },
                "validate": case_validate
            }
            module_case_dir = os.path.join(project_dir, f"ApiProject{belong_project}/ApiModule{belong_module_id}")
            case_path_yml = os.path.join(module_case_dir, f"api/test{case_id}.yml")
            logger.info(f'生成用例yaml文件：{case_yml}')
            with open(case_path_yml, "w", encoding="utf-8") as f:
                yaml.safe_dump(case_yml, f, sort_keys=False, allow_unicode=True)
        else:
            case_name = case_info.get("name")
            belong_project = case_info.get('belong_project_id')
            belong_module_id = case_info.get('belong_module_id')
            include = case_info.get('include')
            author = case_info.get('author')
            request = {
                'base_url': case_info.get('base_url'),
                'variables': case_info.get('variables'),
                'caseSteps': case_info.get('caseSteps'),
            }
            case_obj = TestCaseInfo.objects.create(name=case_name, type_case=case_type, belong_project_id=belong_project, belong_module_id=belong_module_id, include=include, author=author, request=request)
            # 创建用例
            case_id = case_obj.id
            # 公共变量
            cases_variables = {}
            for i in case_info.get("variables"):
                key = i.get('Key')
                Type = i.get('Type')
                value = i.get('Value')
                if Type == "int":
                    cases_variables[key] = int(value)
                elif Type == "float":
                    cases_variables[key] = float(value)
                elif Type == "string":
                    cases_variables[key] = str(value)
                else:
                    cases_variables[key] = value
            # 测试步骤
            test_steps = []
            for step in case_info.get('caseSteps'):
                case_step = dict()
                # 用例名称
                case_step['name'] = step['stepName']
                # 用例变量
                case_variables = {}
                for i in step.get("variables"):
                    key = i.get('Key')
                    Type = i.get('Type')
                    value = i.get('Value')
                    if Type == "int":
                        case_variables[key] = int(value)
                    elif Type == "float":
                        case_variables[key] = float(value)
                    elif Type == "string":
                        case_variables[key] = str(value)
                    else:
                        case_variables[key] = value
                case_step['variables'] = case_variables
                # 请求参数
                case_headers = {}
                for i in step.get("request").get("headers"):
                    key = i.get('Key')
                    value = i.get('Value')
                    case_headers[key] = value
                case_json = {}
                for i in step.get("request").get("json"):
                    key = i.get('Key')
                    Type = i.get('Type')
                    value = i.get('Value')
                    if Type == "int":
                        case_json[key] = int(value)
                    elif Type == "float":
                        case_json[key] = float(value)
                    elif Type == "string":
                        case_json[key] = str(value)
                    else:
                        case_json[key] = value
                case_method = step.get("request").get("method")
                case_url = step.get("request").get("url")
                case_step['request'] = {
                    "url": case_url,
                    "method": case_method,
                    "headers": case_headers,
                    "json": case_json
                }
                # 提取数据
                case_extract = []
                for i in step.get('extract'):
                    extract = dict()
                    key = i.get('Key')
                    Type = i.get('Type')
                    value = i.get('Value')
                    if Type == "int":
                        extract[key] = int(value)
                    elif Type == "float":
                        extract[key] = float(value)
                    elif Type == "string":
                        extract[key] = str(value)
                    else:
                        extract[key] = value
                    case_extract.append(extract)
                case_step['extract'] = case_extract
                # 断言
                case_validate = []
                for i in step.get("validate"):
                    Check = i["Check"]
                    Comparator = i["Comparator"]
                    Type = i.get("Type")
                    Expect = i['Expect']
                    dic = dict()
                    dic["check"] = Check
                    dic["comparator"] = Comparator
                    if Type == "int":
                        dic['expect'] = int(Expect)
                    elif Type == "float":
                        dic['expect'] = float(Expect)
                    elif Type == "string":
                        dic['expect'] = str(Expect)
                    else:
                        dic['expect'] = Expect
                    case_validate.append(dic)
                case_step['validate'] = case_validate
                test_steps.append(case_step)
            # yaml文件内容
            case_yml = {
                'config': {
                    'name': case_name,
                    'variables': cases_variables,
                    'base_url': 'http://' + case_info.get('base_url')
                },
                'teststeps': test_steps
            }
            module_case_dir = os.path.join(base_dir, f"project/ApiProject{belong_project}/ApiModule{belong_module_id}")
            case_path_yml = os.path.join(module_case_dir, f"testcases/test{case_id}.yml")
            with open(case_path_yml, "w", encoding='utf-8') as f:
                yaml.safe_dump(case_yml, f, sort_keys=False, allow_unicode=True)
        # 生成用例配置
        caseConfigAdd(case_debugTalkInfo, case_envInfo)
        data["msg"] = "新增用例成功"
        data["msgCode"] = "1"
    return JsonResponse(data)


def caseEdit(request):
    """
    编辑用例
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == 'PUT':
        # 编辑前的用例信息，用于判断时候项目/模块发生变化
        case_old_info = json.loads(request.body.decode("utf-8")).get("caseOldInfo")
        logger.info(f'原始用例数据---{case_old_info}')
        old_belong_project = int(case_old_info.get('fields').get('belong_project'))
        old_belong_module = int(case_old_info.get('fields').get('belong_module'))
        # 编辑用例并存入到数据库
        case_new_info = json.loads(request.body.decode("utf-8")).get("caseInfo")
        logger.info(f'修改后用例数据---{case_new_info}')
        type_case = case_new_info.get('type_case')
        case_id = case_new_info.get('id')
        obj = TestCaseInfo.objects.get(id=case_id)
        obj.name = case_new_info.get('name')
        obj.type_case = case_new_info.get('type_case')
        obj.belong_project_id = case_new_info.get('belong_project')
        obj.belong_module_id = case_new_info.get('belong_module')
        obj.author = case_new_info.get('author')
        obj.status_case = case_new_info.get('status_case')
        obj.include = case_new_info.get('include')
        if type_case == 'single':
            obj.request = case_new_info.get('request')
        else:
            obj.request = {
                'base_url': case_new_info.get('base_url'),
                'variables': case_new_info.get('variables'),
                'caseSteps': case_new_info.get('caseSteps')
            }
        obj.save()
        data['msgCode'] = '1'
        data['msg'] = '编辑用例成功存入到数据库'
        # 编辑用例后将数据更新到用例文本
        if type_case == 'single':
            # 生成用例文件
            case_id = case_new_info.get('id')
            belong_project = int(case_new_info.get('belong_project'))
            belong_module = int(case_new_info.get('belong_module'))
            # 用例名称
            case_name = case_new_info.get('name')
            # 请求base_url
            base_url = 'http://' + case_new_info.get("request").get('base_url')
            # 请求头
            case_headers = {}
            for i in case_new_info.get("request").get("headers"):
                key = i.get('Key')
                value = i.get('Value')
                case_headers[key] = value
            # 请求数据
            case_json = {}
            for i in case_new_info.get("request").get("json"):
                key = i.get('Key')
                Type = i.get('Type')
                value = i.get('Value')
                if Type == "int":
                    case_json[key] = int(value)
                elif Type == "float":
                    case_json[key] = float(value)
                elif Type == "string":
                    case_json[key] = str(value)
                else:
                    case_json[key] = value
            # 请求方法
            case_method = case_new_info.get("request").get("method")
            # 请求地址
            case_url = case_new_info.get("request").get("url")
            # 变量
            case_variables = {}
            for i in case_new_info.get("request").get("variables"):
                key = i.get('Key')
                Type = i.get('Type')
                value = i.get('Value')
                if Type == "int":
                    case_variables[key] = int(value)
                elif Type == "float":
                    case_variables[key] = float(value)
                elif Type == "string":
                    case_variables[key] = str(value)
                else:
                    case_variables[key] = value
            # 断言
            case_validate = []
            for i in case_new_info.get("request").get("validate"):
                Check = i.get("Check")
                Comparator = i.get("Comparator")
                Type = i.get("Type")
                Expect = i.get('Expect')
                dic = dict()
                dic["check"] = Check
                dic["comparator"] = Comparator
                if Type == "int":
                    dic['expect'] = int(Expect)
                elif Type == "float":
                    dic['expect'] = float(Expect)
                elif Type == "string":
                    dic['expect'] = str(Expect)
                else:
                    dic['expect'] = Expect
                case_validate.append(dic)
            # yaml文件内容
            case_yml = {
                "name": case_name,
                "variables": case_variables,
                'base_url': base_url,
                "request": {
                    "url": case_url,
                    "method": case_method,
                    "headers": case_headers,
                    "json": case_json
                },
                "validate": case_validate
            }
            logger.info(f'生成yaml文件---{case_yml}')
            module_case_dir = os.path.join(project_dir, f"ApiProject{belong_project}/ApiModule{belong_module}")
            case_path_yml = os.path.join(module_case_dir, f"api/test{case_id}.yml")
            data["msg"] = "编辑单一接口用例成功"
        else:
            # 编辑
            case_name = case_new_info.get("name")
            belong_project = case_new_info.get('belong_project')
            belong_module = case_new_info.get('belong_module')
            # 创建用例
            case_id = case_new_info.get('id')
            # 公共变量
            cases_variables = {}
            for i in case_new_info.get("variables"):
                key = i.get('Key')
                Type = i.get('Type')
                value = i.get('Value')
                if Type == "int":
                    cases_variables[key] = int(value)
                elif Type == "float":
                    cases_variables[key] = float(value)
                elif Type == "string":
                    cases_variables[key] = str(value)
                else:
                    cases_variables[key] = value
            # 测试步骤
            test_steps = []
            for step in case_new_info.get('caseSteps'):
                case_step = dict()
                # 用例名称
                case_step['name'] = step['stepName']
                # 用例变量
                case_variables = {}
                for i in step.get("variables"):
                    key = i.get('Key')
                    Type = i.get('Type')
                    value = i.get('Value')
                    if Type == "int":
                        case_variables[key] = int(value)
                    elif Type == "float":
                        case_variables[key] = float(value)
                    elif Type == "string":
                        case_variables[key] = str(value)
                    else:
                        case_variables[key] = value
                case_step['variables'] = case_variables
                # 请求参数
                case_headers = {}
                for i in step.get("request").get("headers"):
                    key = i.get('Key')
                    value = i.get('Value')
                    case_headers[key] = value
                case_json = {}
                for i in step.get("request").get("json"):
                    key = i.get('Key')
                    Type = i.get('Type')
                    value = i.get('Value')
                    if Type == "int":
                        case_json[key] = int(value)
                    elif Type == "float":
                        case_json[key] = float(value)
                    elif Type == "string":
                        case_json[key] = str(value)
                    else:
                        case_json[key] = value
                case_method = step.get("request").get("method")
                case_url = step.get("request").get("url")
                case_step['request'] = {
                    "url": case_url,
                    "method": case_method,
                    "headers": case_headers,
                    "json": case_json
                }
                # 提取数据
                case_extract = []
                for i in step.get('extract'):
                    extract = dict()
                    key = i.get('Key')
                    Type = i.get('Type')
                    value = i.get('Value')
                    if Type == "int":
                        extract[key] = int(value)
                    elif Type == "float":
                        extract[key] = float(value)
                    elif Type == "string":
                        extract[key] = str(value)
                    else:
                        extract[key] = value
                    case_extract.append(extract)
                case_step['extract'] = case_extract
                # 断言
                case_validate = []
                for i in step.get("validate"):
                    Check = i["Check"]
                    Comparator = i["Comparator"]
                    Type = i.get("Type")
                    Expect = i['Expect']
                    dic = dict()
                    dic["check"] = Check
                    dic["comparator"] = Comparator
                    if Type == "int":
                        dic['expect'] = int(Expect)
                    elif Type == "float":
                        dic['expect'] = float(Expect)
                    elif Type == "string":
                        dic['expect'] = str(Expect)
                    else:
                        dic['expect'] = Expect
                    case_validate.append(dic)
                case_step['validate'] = case_validate
                test_steps.append(case_step)
            # yaml文件内容
            case_yml = {
                'config': {
                    'name': case_name,
                    'variables': cases_variables,
                    'base_url': 'http://' + case_new_info.get('base_url')
                },
                'teststeps': test_steps
            }
            module_case_dir = os.path.join(base_dir, f"project/ApiProject{belong_project}/ApiModule{belong_module}")
            case_path_yml = os.path.join(module_case_dir, f"testcases/test{case_id}.yml")
            data["msg"] = "编辑流程接口用例成功"
        # 生成用例文件
        # 删除原用例文件
        module_case_old_dir = os.path.join(project_dir, f"ApiProject{old_belong_project}/ApiModule{old_belong_module}")
        if type_case == 'single':
            case_old_path_yml = os.path.join(module_case_old_dir, f"api/test{case_id}.yml")
        else:
            case_old_path_yml = os.path.join(module_case_old_dir, f"testcases/test{case_id}.yml")
        os.unlink(case_old_path_yml)
        logger.info(f"删除原用例文件:{case_old_path_yml}")
        with open(case_path_yml, "w", encoding='utf-8') as f:
            yaml.safe_dump(case_yml, f, sort_keys=False, allow_unicode=True)
        logger.info(f"生成新用例文件:{case_path_yml}")
        data["msgCode"] = "1"
    elif request.method == 'GET':
        case_new_info = json.loads(request.GET.get('caseInfo'))
        type_case = case_new_info.get('fields').get('type_case')
        request_field = eval(case_new_info.get('fields').get('request'))
        # 重构数据结构
        if type_case == 'single':
            data['caseList'] = {
                'id': case_new_info.get('pk'),
                'name': case_new_info.get('fields').get('name'),
                'type_case': case_new_info.get('fields').get('type_case'),
                'belong_project': int(case_new_info.get('fields').get('belong_project')),
                'belong_module': case_new_info.get('fields').get('belong_module'),
                'author': case_new_info.get('fields').get('author'),
                'status_case': case_new_info.get('fields').get('status_case'),
                'request': {
                    'base_url': request_field.get('base_url'),
                    'url': request_field.get('url'),
                    'method': request_field.get('method'),
                    'headers': request_field.get('headers'),
                    'json': request_field.get('json'),
                    'validate': request_field.get('validate'),
                    'variables': request_field.get('variables'),
                },
            }
        else:
            data['caseList'] = {
                'id': case_new_info.get('pk'),
                'name': case_new_info.get('fields').get('name'),
                'type_case': case_new_info.get('fields').get('type_case'),
                'belong_project': int(case_new_info.get('fields').get('belong_project')),
                'belong_module': case_new_info.get('fields').get('belong_module'),
                'author': case_new_info.get('fields').get('author'),
                'status_case': case_new_info.get('fields').get('status_case'),
                'base_url': request_field.get('base_url'),
                'variables': request_field.get('variables'),
                'caseSteps': request_field.get('caseSteps'),
            }
        data['msgCode'] = '1'
        data['msg'] = '获取待编辑用例成功'
    else:
        logger.info("请求方式错误")
    response = JsonResponse(data=data)
    response['Access-Control-Allow-Origin'] = True
    return response


# api/searchCase/
def searchCase(request):
    """
    用例搜索
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        searchInfo = json.loads(request.GET.get('searchInfo'))
        logger.info(f'查询的用例信息：{searchInfo}')
        module_id = searchInfo.get('moduleId')
        case_name = searchInfo.get('caseName')
        if module_id:
            case_list = TestCaseInfo.objects.filter(belong_module_id=module_id).filter(name__icontains=case_name)
        else:
            case_list = TestCaseInfo.objects.all()
        data['caseNum'] = case_list.count()
        page_size = searchInfo.get('pageSize')
        pg = Paginator(case_list, page_size)
        if data['caseNum'] <= page_size:  # 当前端页码处于非第一页但查询结果又小于当前每页显示数量时，将页码重置为第一页.需要将页码传递给前端
            current_page = 1
        else:
            current_page = searchInfo.get('currentPage')  # 当前页码
        case_list = pg.page(current_page)
        data['currentPage'] = current_page
        data["msg"] = "查询项目成功"
        data["msgCode"] = '1'
        data["username"] = username
        data["caseList"] = json.loads(serialize("json", case_list))
    return JsonResponse(data=data)


# /api/caseDel/
def caseDel(request):
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "DELETE":
        case_info = json.loads(request.body.decode("utf-8")).get('caseInfo')
        print(case_info, "8888888888888")
        project_id = case_info.get('fields').get('belong_project')
        module_id = case_info.get('fields').get('belong_module')
        type_case = case_info.get('fields').get('type_case')
        case_id = case_info.get('pk')
        logger.info(f"获取待删除的模块Id为：{case_id}")
        case_obj = TestCaseInfo.objects.get(id=case_id)
        report_path = case_obj.report_path
        # 删除数据库中的用例
        case_obj.delete()
        # 删除用例执行文件
        module_case_dir = os.path.join(project_dir, f"ApiProject{project_id}/ApiModule{module_id}")
        if type_case == 'single':
            case_path = os.path.join(module_case_dir, f"api/test{case_id}.yml")
        else:
            case_path = os.path.join(module_case_dir, f"testcases/test{case_id}.yml")
        os.unlink(case_path)
        # 删除测试报告
        if report_path:
            os.unlink(report_path)
        data["msgCode"] = "1"
        data["msg"] = f"删除陈功:{case_obj}"
    return JsonResponse(data=data)


# api/runCase/
def runCase(request):
    """
    运行单个用例
    :param request:
    :return:
    """

    data = dict()
    username = request.session.get("username")
    data["username"] = username
    flag = True
    if request.method == "POST":
        case_list = json.loads(request.body.decode("utf-8")).get('caseInfo')
        # 执行单条用例时，序列化用例信息,多条时默认用例列表
        case_list = [case_list] if not isinstance(case_list, list) else case_list
        # celery异步运行用例
        logger.info(f"异步执行用例")
        flag = runCaseWorker.delay(case_list)
    if flag:
        data["msgCode"] = "1"
        data["msg"] = "用例执行成功"
    else:
        data["msgCode"] = "-1"
        data["msg"] = "用例执行失败"
    return JsonResponse(data=data)


# /api/debugtalk/
def debugtalk(request):
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        module_id = request.GET.get('moduleId')
        obj = DebugTalk.objects.get(belong_module_id=module_id)
        data['debugtalkInfo'] = {
            'id': obj.id,
            'belong_project': obj.belong_project_id,
            'belong_module': obj.belong_module_id,
            'debugtalk': obj.debugtalk,
        }
    return JsonResponse(data=data)


# /api/envInfo/
def envInfo(request):
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == "GET":
        module_id = request.GET.get('moduleId')
        obj = EnvInfo.objects.get(belong_module_id=module_id)
        data['envInfo'] = {
            'id': obj.id,
            'belong_project': obj.belong_project_id,
            'belong_module': obj.belong_module_id,
            'content': obj.content,
        }
    return JsonResponse(data=data)


# /api/caseConfigSave/
def caseConfigSave(request):
    """
    用例环境配置，包括debugtalk.py和.env
    :param request:
    :return:
    """
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == 'POST':
        data_rq = json.loads(request.body.decode("utf-8"))
        # 保存debugtalk到数据库
        debugtalk_info = data_rq.get('debugtalkInfo')
        env_info = data_rq.get('envInfo')
        caseConfigAdd(debugtalk_info, env_info)
        data['msgCode'] = '1'
    return JsonResponse(data=data)


# /api/caseReport/
def caseReport(request):
    data = dict()
    username = request.session.get("username")
    data["username"] = username
    if request.method == 'GET':
        report_path = request.GET.get('reportName')
        with open(report_path, 'r', encoding='utf-8') as f:
            data['report'] = f.read()
    return JsonResponse(data)
